package com.bbx.taxi.client;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Application;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.bbx.androidapi.util.DebugUtil;
import com.bbx.androidapi.util.SharedPreUtil;
import com.bbx.api.sdk.SDK;
import com.bbx.api.sdk.model.passanger.Token;
import com.bbx.api.util.LogUtils;
import com.bbx.api.util.SharedPreEncryptUtil;
import com.bbx.taxi.client.Activity.login.LoginActivity;
import com.bbx.taxi.client.Adapter.City.CityAdapter;
import com.bbx.taxi.client.Bean.City;
import com.bbx.taxi.client.Bean.Value;
import com.bbx.taxi.client.Bean.Attribute.MainAttribute;
import com.bbx.taxi.client.Bean.Extra.MainMsg;
import com.bbx.taxi.client.DB.CityDB;
import com.bbx.taxi.client.Fragment.CarpoolingFragment;
import com.bbx.taxi.client.Fragment.CharteredCarFragment;
import com.bbx.taxi.client.Fragment.CityCarFragment;
import com.bbx.taxi.client.Fragment.ExpressFragment;
import com.bbx.taxi.client.Service.LoginService;
import com.bbx.taxi.client.Util.AppStarted;
import com.bbx.taxi.client.Util.NetworkDetector;
import com.bbx.taxi.official.R;

public class MyApplication extends Application implements
		OnGetGeoCoderResultListener {
	private CityDB cityDB;
	public static final int CITY_LIST_SCUESS = 0;
	private static final String FORMAT = "^[a-z,A-Z].*$";
	private static MyApplication mApplication;
	private List<City> cityList;
	// 首字母集
	private List<String> mSections;
	// 根据首字母存放数据
	private Map<String, List<City>> mMap;
	// 首字母位置集
	private List<Integer> mPositions;
	// 首字母对应的位置
	private Map<String, Integer> mIndexer;
	public static boolean isCityListComplite;
	public MyLocationListenner mMyLocationListener;
	public LocationClientOption option;// 设置定位信息
	public LocationClient locationclient;// 用来定位
	public BDLocation mLocation;
	public String loctionType = "";// 定位类型
	public String loctionCity = "";// 定位城市
	public double longitude = 0;// 经度
	public double latitude = 0;// 纬度
	public static ArrayList<EventHandler> mListeners = new ArrayList<EventHandler>();
	/** 电话 */
	public String user_phone = "";
	/** 名字 */
	public String user_name = "";
	/**不可更改的名字*/
	public String real_name="";
	/** 电话 */
	public String real_phone = "";
	/**角色名字，如公务员*/
	public String role_name="";
	public String authority="";
	/** 性别 */
	public String user_sex = "";
	/** 用户类型type”:0乘客,1司机,2管理员 */
	public String user_type = "";
	/** token */
	public String token = "";
	/** uid */
	public String uid = "";
	public LoginService loginservice;
	/** 第一次打开客户端 */
	public boolean isFirstClient = false;
	/** 第一次启动该mainActivity */
	public boolean isFirstActivity = true;
	private GeoCoder mSearch = null; // 地理编码
	
	public String getRoleName(){
		return role_name==null?"":role_name;
	}
	public String getRealName(){
		return real_name==null?"":real_name;
	}
	public String getUserName(){
		return user_name==null?"":user_name;
	}
	public String getUserphone(){
		return user_phone==null?"":user_phone;
	}
	public String getRealPhone(){
		return real_phone==null?"":real_phone;
	}

	public String getUid() {
		if (uid.equals("")) {
			Token Mytoken = SharedPreEncryptUtil.getStringEncryptValue(this,
					SharedPreEncryptUtil.TokenAndUid, "");
			if (Mytoken != null && !Mytoken.equals(""))
				uid = Mytoken.uid;
		}
		return uid;
	}

	public String getToken() {
		if (token.equals("")) {
			Token Mytoken = SharedPreEncryptUtil.getStringEncryptValue(this,
					SharedPreEncryptUtil.TokenAndUid, "");
			if (Mytoken != null && !Mytoken.equals(""))
				token = Mytoken.access_token;
		}
		return token;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public static Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case CITY_LIST_SCUESS:
				isCityListComplite = true;
				if (mListeners.size() > 0)// 通知接口完成加载
					for (EventHandler handler : mListeners) {
						handler.onCityComplite();
					}
				break;
			default:
				break;
			}
		}
	};

	public static synchronized MyApplication getInstance() {
		return mApplication;
	}

	@Override
	public void onCreate() {
		loctionCity = this.getString(R.string.default_city);
		// TODO Auto-generated method stub
		// 实例化ClientBox
		DebugUtil.isDebug = false;
		SDK.GetSDK().init(getApplicationContext());
		LogUtils.initConfig(this, Value.BBX_PATH);
		init();
		onLocation();
		// 加载城市
		initData();

	}
    
	public void init() {
		// 获取本地存储的电话
		user_phone = SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.phone, "");
		// 获取名字
		user_name = SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.user_name, "");
		// 获取名字
		real_name = SharedPreUtil.getStringValue(this,
						SharedPreEncryptUtil.real_name, "");
		//获取角色名字
		role_name = SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.role_name, "");
		//获取用户电话
		real_phone = SharedPreUtil.getStringValue(this,
						SharedPreEncryptUtil.real_phone, "");
		authority= SharedPreUtil.getStringValue(this,
				SharedPreEncryptUtil.authority, "");
		MainAttribute main = MainAttribute.getInstance();
		main.setTel(getUserphone());
		main.setName((getRealName() != null && !getRealName().equals("")) ? getRealName()
				: main.getName());
	}
	/**
	 * 定位城市
	 */
	public void onLocation() {
		SDKInitializer.initialize(this);
		mMyLocationListener = new MyLocationListenner();
		loctionType = getApplicationContext()
				.getString(R.string.loctionType_no);
		option = new LocationClientOption();// 设置定位的一些信息
		option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
		option.setOpenGps(true);// 是否打开gps
		option.setIsNeedAddress(true);
		option.setCoorType("bd09ll"); // 设置坐标类型为bd09ll
		// option.disableCache(true); // 禁止启用缓存定位
		option.setScanSpan(5000); // 定时定位，每隔5秒钟定位一
		locationclient = new LocationClient(this.getApplicationContext());// 用来定位
	}

	/**
	 * 重新定位
	 */
	public void onStartLocation() {
		LogUtils.e("", "开始定位");
		locationclient.setLocOption(option);
		locationclient.registerLocationListener(mMyLocationListener);
		locationclient.start();
	};

	public void onStopLocation() {
		LogUtils.e("", "取消定位");
		locationclient.setLocOption(null);
		locationclient.unRegisterLocationListener(mMyLocationListener);
		locationclient.stop();
	}

	private void initData() {
		// TODO Auto-generated method stub
		mApplication = this;
		initCityList();
	}
    /**
     * 判断是否有登陆
     */
    public boolean isUidAndTokenNull(){
    	if (getUid() != null &&getToken() != null&&!getUid().equals("")
				&& !getToken().equals("")) {
    		return false;
		} else {
			return true;
		}
    }
	public synchronized CityDB getCityDB() {
		if (cityDB == null)
			cityDB = openCityDB();
		return cityDB;
	}

	private CityDB openCityDB() {
		String path = "/data"
				+ Environment.getDataDirectory().getAbsolutePath()
				+ File.separator + AppStarted.getAppPackageName(this) + File.separator
				+ CityDB.CITY_DB_NAME;
		File db = new File(path);
		if (!db.exists()) {
			// L.i("db is not exists");
			try {
				InputStream is = getAssets().open("city.db");
				FileOutputStream fos = new FileOutputStream(db);
				int len = -1;
				byte[] buffer = new byte[1024];
				while ((len = is.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
					fos.flush();
				}
				fos.close();
				is.close();
			} catch (IOException e) {
				LogUtils.e("", e.getMessage() + "");
				e.printStackTrace();
				Toast.makeText(mApplication, e.getMessage(), Toast.LENGTH_SHORT)
						.show();
				System.exit(0);
			}
		}
		return new CityDB(this, path);
	}

	public List<City> getCityList() {
		return cityList;
	}

	public List<String> getSections() {
		return mSections;
	}

	public Map<String, List<City>> getMap() {
		return mMap;
	}

	public List<Integer> getPositions() {
		return mPositions;
	}

	public Map<String, Integer> getIndexer() {
		return mIndexer;
	}

	public boolean isCityListComplite() {
		return isCityListComplite;
	}

	private void initCityList() {
		cityList = new ArrayList<City>();
		mSections = new ArrayList<String>();
		mMap = new HashMap<String, List<City>>();
		mPositions = new ArrayList<Integer>();
		mIndexer = new HashMap<String, Integer>();
		cityDB = openCityDB();// 这个必须最先复制完,所以我放在单线程中处理
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				isCityListComplite = false;
				// prepareCityList();
				// mHandler.sendEmptyMessage(CITY_LIST_SCUESS);
			}
		}).start();
	}

	/**
	 * 城市列表设置成功。
	 */
	public void onPrepareCity(List<City> cityList) {
		isCityListComplite = false;
		prepareCityList(cityList);
		mHandler.sendEmptyMessage(CITY_LIST_SCUESS);
	}

	public boolean prepareCityList(List<City> cityList) {
		// cityList = cityDB.getAllCity();// 获取数据库中所有城市
		this.cityList.clear();
		this.mSections.clear();
		this.mMap.clear();
		this.mPositions.clear();
		this.cityList.addAll(cityList);
		for (City city : cityList) {
			String firstName = city.getFirstPY();// 第一个字拼音的第一个字母
			if (firstName.matches(FORMAT)) {
				if (mSections.contains(firstName)) {
					mMap.get(firstName).add(city);
				} else {
					mSections.add(firstName);
					List<City> list = new ArrayList<City>();
					list.add(city);
					mMap.put(firstName, list);
				}
			} else {
				if (mSections.contains("#")) {
					mMap.get("#").add(city);
				} else {
					mSections.add("#");
					List<City> list = new ArrayList<City>();
					list.add(city);
					mMap.put("#", list);
				}
			}
		}
		Collections.sort(mSections);// 按照字母重新排序
		// 第一选项加入定位城市
		if (loctionCity != null && !loctionCity.equals("")) {
			String group = CityAdapter.Location_title;
			mSections.add(0, group);
			List<City> LocationCity_list = new ArrayList<City>();
			City city = new City();
			city.setCity(loctionCity);
			LocationCity_list.add(city);
			mMap.put(group, LocationCity_list);
		}
//		//加入已开通城市
//		String group = CityAdapter.open_title;
//		mSections.add(group);
//		mMap.put(group, cityList);
		///
		int position = 0;
		for (int i = 0; i < mSections.size(); i++) {
			mIndexer.put(mSections.get(i), position);// 存入map中，key为首字母字符串，value为首字母在listview中位置
			mPositions.add(position);// 首字母在listview中位置，存入list中
			position += mMap.get(mSections.get(i)).size();// 计算下一个首字母在listview的位置
		}
		return true;
	}

	public static abstract interface EventHandler {
		public abstract void onCityComplite();

		public abstract void onNetChange();
	}

	public void setEventHandler(EventHandler hEventHandler) {
		if (!mListeners.contains(hEventHandler))
			mListeners.add(hEventHandler);
	}

	public void removeEventHandler(EventHandler hEventHandler) {
		mListeners.remove(hEventHandler);
	}

	/**
	 * 定位SDK监听函数
	 */
	public class MyLocationListenner implements BDLocationListener {

		@Override
		public void onReceiveLocation(BDLocation location) {
			// map view 销毁后不在处理新接收的位置
			if (location == null)
				return;
			mLocation = location;
			if (location.getLocType() == BDLocation.TypeGpsLocation) {
				// GPS定位
				loctionType = getApplicationContext().getString(
						R.string.loctionType_gps);
			} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
				// 网络定位
				loctionType = getApplicationContext().getString(
						R.string.loctionType_network);
			}
			longitude = location.getLongitude();
			latitude = location.getLatitude();
			if (location.getCity() != null&&!location.getCity().equals("null")) {
				loctionCity = location.getCity();
				if (!mOnLocationResultListener_list.isEmpty()) {
					for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
						mOnLocationResultListener_list.get(i).onLocationResult(
								location);
					}
				}
			} else {
				onGeoCoder(latitude, longitude);
			}

		}

		public void onReceivePoi(BDLocation poiLocation) {
		}
	}

	/**
	 * 地理编码搜索
	 */
	public void onGeoCoder(double latitude, double longitude) {
		if (NetworkDetector.detect(this)) {
			LatLng ptCenter = new LatLng(latitude, longitude);
			if (ptCenter.latitude == 0 || ptCenter.longitude == 0) {
				if (!mOnLocationResultListener_list.isEmpty()) {
					for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
						mOnLocationResultListener_list.get(i).onLocationFail(true);
					}
				}
				return;
			}
			// 初始化搜索模块，注册事件监听
			mSearch = GeoCoder.newInstance();
			mSearch.setOnGetGeoCodeResultListener(this);
			// 反Geo搜索
			mSearch.reverseGeoCode(new ReverseGeoCodeOption()
					.location(ptCenter));
		} else {
			if (!mOnLocationResultListener_list.isEmpty()) {
				for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
					mOnLocationResultListener_list.get(i).onLocationFail(false);
				}
			}
		}
	}

	public ArrayList<OnLocationResultListener> mOnLocationResultListener_list = new ArrayList<OnLocationResultListener>();

	/**
	 * 自定义定位监听结果
	 */
	public interface OnLocationResultListener {
		/**
		 * 定位结果
		 */
		public void onLocationResult(BDLocation location);

		public void onLocationResult(ReverseGeoCodeResult result);

		public void onLocationFail(boolean isnet);
	}

	public void setOnLocationResultListener(
			OnLocationResultListener mOnLocationResultListener) {
		if (!mOnLocationResultListener_list.contains(mOnLocationResultListener))
			mOnLocationResultListener_list.add(mOnLocationResultListener);
	}

	public void removeOnLocationResultListener(
			OnLocationResultListener mOnLocationResultListener) {
		mOnLocationResultListener_list.remove(mOnLocationResultListener);
	}

	public ServiceConnection mSc = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			loginservice = ((LoginService.MyBinder) service).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			loginservice = null;
		}
	};

	/**
	 * 地理编码结果（地理到经纬度的结果）
	 */
	@Override
	public void onGetGeoCodeResult(GeoCodeResult result) {
		// TODO Auto-generated method stub

	}

	/**
	 * 地理编码结果（经纬度到地址的结果）
	 */
	@Override
	public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
		if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR
				|| result.getPoiList() == null) {

		} else {
			loctionCity = result.getAddressDetail().city;
			if(loctionCity!=null){
			if (!mOnLocationResultListener_list.isEmpty()) {
				for (int i = 0; i < mOnLocationResultListener_list.size(); i++) {
					mOnLocationResultListener_list.get(i).onLocationResult(
							result);
				}
		      }
			}
		}

	}
}
